 
package com.zdkj.subway.rca.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;

import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;


import com.zdkj.subway.rca.dto.out.SwCkConfiirmProcessBomEpaymentDTO;
import com.zdkj.subway.rca.entity.SwCkConfiirmProcessBomEpayment;
import com.zdkj.subway.rca.mapper.SwCkConfiirmProcessBomEpaymentMapper;
import com.zdkj.subway.rca.service.SwCkConfiirmProcessBomEpaymentService;
import com.zdkj.subway.rca.util.LocalDateConverter;
import com.zdkj.subway.rca.util.LocalDateTimeConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.format.DateTimeFormatter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 对账确认过程-BOM电子支付表
 *
 * @author stw
 * @date 2020-10-25 16:42:55
 */
@Service
public class SwCkConfiirmProcessBomEpaymentServiceImpl extends ServiceImpl<SwCkConfiirmProcessBomEpaymentMapper, SwCkConfiirmProcessBomEpayment> implements SwCkConfiirmProcessBomEpaymentService {
    private static final Logger log = LoggerFactory.getLogger(SwCkConfiirmProcessBomEpaymentServiceImpl.class);
    public List<SwCkConfiirmProcessBomEpayment> listSwCkConfiirmProcessBomEpayment(String startDate, String endDate, String confirmStatus, String ordflag) {
        List<SwCkConfiirmProcessBomEpayment>  list = this.baseMapper.listSwCkConfiirmProcessBomEpayment(startDate,endDate,confirmStatus,ordflag);
        for (SwCkConfiirmProcessBomEpayment swCkConfiirmProcessBomEpayment : list) {
            String url = "/rca/swckbankverifypayment/previewDiff?tradeDateStr=_tradeDateStr_&verfiyConfirmFlag=_verfiyConfirmFlag_";
            DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String dateStr = swCkConfiirmProcessBomEpayment.getTradeDate().format(fmt);
            if(swCkConfiirmProcessBomEpayment.getDiffAlipyAmount() != 0){
                swCkConfiirmProcessBomEpayment.setDiffAlipayUrl(url.replace("_tradeDateStr_",dateStr).replace("_verfiyConfirmFlag_","4"));
            }
            if(swCkConfiirmProcessBomEpayment.getDiffWechartAmount() != 0){
                swCkConfiirmProcessBomEpayment.setDiffWechartUrl(url.replace("_tradeDateStr_",dateStr).replace("_verfiyConfirmFlag_","5"));
            }
			if(swCkConfiirmProcessBomEpayment.getDiffPosAmount() != 0){
                swCkConfiirmProcessBomEpayment.setDiffPosUrl(url.replace("_tradeDateStr_",dateStr).replace("_verfiyConfirmFlag_","24"));
            }
        }
        return list;
    }

    /**
     * 导出
     * @param
     * @return
     * @throws IOException
     */
    @Override
    public void exportExcel(String startDate, String endDate,String confirmStatus,String ordflag, HttpServletResponse response) {
        List<SwCkConfiirmProcessBomEpayment>  list = this.baseMapper.listSwCkConfiirmProcessBomEpayment(startDate,endDate,confirmStatus,ordflag);
        BigDecimal hundred = new BigDecimal(100);
        List<SwCkConfiirmProcessBomEpaymentDTO> records = new ArrayList<>();
        for (SwCkConfiirmProcessBomEpayment obj : list){
            SwCkConfiirmProcessBomEpaymentDTO dto = new SwCkConfiirmProcessBomEpaymentDTO();
            dto.setTradeDate(obj.getTradeDate());
            dto.setAlipayTradeAmount(new BigDecimal(obj.getAlipayTradeAmount()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
            dto.setAlipayTradeServiceAmount(new BigDecimal(obj.getAlipayTradeServiceAmount()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
            dto.setAlipayTradeBankAmount(new BigDecimal(obj.getAlipayTradeBankAmount()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
            dto.setWechartTradeAmount(new BigDecimal(obj.getWechartTradeAmount()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
            dto.setWechartTradeServiceAmount(new BigDecimal(obj.getWechartTradeServiceAmount()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
            dto.setWechartTradeBankAmount(new BigDecimal(obj.getWechartTradeBankAmount()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
			dto.setPosTradeAmount(new BigDecimal(obj.getPosTradeAmount()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
            dto.setPosTradeServiceAmount(new BigDecimal(obj.getPosTradeServiceAmount()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
            dto.setPosTradeBankAmount(new BigDecimal(obj.getPosTradeBankAmount()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
            dto.setDiffAlipyAmount(new BigDecimal(obj.getDiffAlipyAmount()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
            dto.setDiffWechartAmount(new BigDecimal(obj.getDiffWechartAmount()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
			dto.setDiffPosAmount(new BigDecimal(obj.getDiffPosAmount()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
            dto.setConfirmStatus("1".equals(obj.getConfirmStatus()) ? "已确认" : "未确认");
            records.add(dto);
        }

        InputStream excelTemplateIs = null;
        try {response.reset(); // 非常重要
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            final String fileName = URLEncoder.encode("BOM电子支付数据", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + System.currentTimeMillis() + ".xlsx");

            // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
            // {} 代表普通变量 {.} 代表是list的变量

            excelTemplateIs = this.getClass().getResourceAsStream("/static/excel/template/export/SwCkConfiirmProcessBomEpaymentExcelTemplate.xlsx");

            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).registerConverter(new LocalDateTimeConverter()).registerConverter(new LocalDateConverter()).withTemplate(excelTemplateIs).build();
            WriteSheet writeSheet = EasyExcel.writerSheet("BOM电子支付数据").build();
            // 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行，然后下面的数据往后移动。默认 是false，会直接使用下一行，如果没有则创建。
            // forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了，所以慎用
            // 简单的说 如果你的模板有list,且list不是最后一行，下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
            // 如果数据量大 list不是最后一行 参照另一个
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
            excelWriter.fill(records, fillConfig, writeSheet);

            Map<String, Object> map = new HashMap<>();
            map.putAll(getSum(records));
            excelWriter.fill(map, writeSheet);
            excelWriter.finish();

        } catch (Exception e) {
            e.printStackTrace();
            log.error("导出BOM电子支付数据错误");
        } finally {
            if(excelTemplateIs != null){
                try {
                    excelTemplateIs.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }

            }
        }
    }

    /**
     * 计算合计
     * @param records
     * @return
     */
    private Map<String,Object> getSum(List<SwCkConfiirmProcessBomEpaymentDTO> records){
        Map<String,Object> map = new HashMap<>();
        BigDecimal totalAlipayTradeAmount = new BigDecimal("0.00");
        BigDecimal totalAlipayTradeServiceAmount = new BigDecimal("0.00");
        BigDecimal totalAlipayTradeBankAmount = new BigDecimal("0.00");
        BigDecimal totalWechartTradeAmount = new BigDecimal("0.00");
        BigDecimal totalWechartTradeServiceAmount = new BigDecimal("0.00");
        BigDecimal totalWechartTradeBankAmount = new BigDecimal("0.00");
		BigDecimal totalPosTradeAmount = new BigDecimal("0.00");
        BigDecimal totalPosTradeServiceAmount = new BigDecimal("0.00");
        BigDecimal totalPosTradeBankAmount = new BigDecimal("0.00");
        BigDecimal totalDiffAlipyAmount = new BigDecimal("0.00");
        BigDecimal totalDiffWechartAmount = new BigDecimal("0.00");
		BigDecimal totalDiffPosAmount = new BigDecimal("0.00");

        for (SwCkConfiirmProcessBomEpaymentDTO dto : records) {
            totalAlipayTradeAmount = totalAlipayTradeAmount.add(dto.getAlipayTradeAmount());
            totalAlipayTradeServiceAmount = totalAlipayTradeServiceAmount.add(dto.getAlipayTradeServiceAmount());
            totalAlipayTradeBankAmount = totalAlipayTradeBankAmount.add(dto.getAlipayTradeBankAmount());
            totalWechartTradeAmount = totalWechartTradeAmount.add(dto.getWechartTradeAmount());
            totalWechartTradeServiceAmount = totalWechartTradeServiceAmount.add(dto.getWechartTradeServiceAmount());
            totalWechartTradeBankAmount = totalWechartTradeBankAmount.add(dto.getWechartTradeBankAmount());
			totalPosTradeAmount = totalPosTradeAmount.add(dto.getPosTradeAmount());
            totalPosTradeServiceAmount = totalPosTradeServiceAmount.add(dto.getPosTradeServiceAmount());
            totalPosTradeBankAmount = totalPosTradeBankAmount.add(dto.getPosTradeBankAmount());
            totalDiffAlipyAmount = totalDiffAlipyAmount.add(dto.getDiffAlipyAmount());
            totalDiffWechartAmount = totalDiffWechartAmount.add(dto.getDiffWechartAmount());
			totalDiffPosAmount = totalDiffPosAmount.add(dto.getDiffPosAmount());
        }
        map.put("totalAlipayTradeAmount",totalAlipayTradeAmount);
        map.put("totalAlipayTradeServiceAmount",totalAlipayTradeServiceAmount);
        map.put("totalAlipayTradeBankAmount",totalAlipayTradeBankAmount);
        map.put("totalWechartTradeAmount",totalWechartTradeAmount);
        map.put("totalWechartTradeServiceAmount",totalWechartTradeServiceAmount);
        map.put("totalWechartTradeBankAmount",totalWechartTradeBankAmount);
		map.put("totalPosTradeAmount",totalPosTradeAmount);
        map.put("totalPosTradeServiceAmount",totalPosTradeServiceAmount);
        map.put("totalPosTradeBankAmount",totalPosTradeBankAmount);
        map.put("totalDiffAlipyAmount",totalDiffAlipyAmount);
        map.put("totalDiffWechartAmount",totalDiffWechartAmount);
		map.put("totalDiffPosAmount",totalDiffPosAmount);
        return map;
    }

}
